﻿using System;
using System.ComponentModel;
using System.Reflection;
using System.Web.UI;

namespace DigitalSum.Web.Extensions
{
    internal static class ControlExtensions
    {
        #region STATIC METHODS

        internal static bool GetDefaultPropertyValue(this Control control, out object value)
        {
            object[] attribs = control.GetType().GetCustomAttributes(typeof(DefaultPropertyAttribute), false);
            if (attribs.Length > 0)
            {
                DefaultPropertyAttribute defaultPropertyAttribute = (DefaultPropertyAttribute)attribs[0];
                value = GetPropertyValue(control, defaultPropertyAttribute.Name);
                return true;
            }
            else
            {
                value = null;
                return false;
            }
        }

        internal static object GetPropertyValue(this Control control, string propertyName)
        {
            object value = null;

            if (control != null)
            {
                PropertyInfo propInfo = control.GetType().GetProperty(propertyName);
                value = propInfo.GetValue(control, null);
            }
            return value;
        }

        #endregion
    }

    internal class ControlHelper
    {
        public ControlHelper() { }

        private static ControlHelper _instance;
        public static ControlHelper GetInstance()
        {
            if (_instance == null)
                _instance = new ControlHelper();
            return _instance;
        }

        #region METHODS

        internal static string AssembleControlID(string name, object container)
        {
            string controlID = null;

            BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;

            MemberInfo[] infos = container.GetType().GetMembers(bindFlags);//BindingFlags.Public | BindingFlags.Instance);

            if (infos != null && infos.Length > 0)
            {
                //MemberInfo member = infos[0];
                foreach (MemberInfo member in infos)
                {
                    if (member.Name == name)
                    {
                        object source = container;

                        if (member.MemberType == MemberTypes.Field)
                        {
                            FieldInfo SourceField = source.GetType().GetField(name, bindFlags);
                            if (SourceField != null)
                            {
                                Control sourceControl = SourceField.GetValue(source) as Control;
                                if (sourceControl != null)
                                    controlID = sourceControl.UniqueID;
                            }
                            else
                                throw new NotSupportedException("The field corresponding to ControlID may not be read");
                        }
                        else if (member.MemberType == MemberTypes.Property)
                        {
                            PropertyInfo SourceField = source.GetType().GetProperty(name, bindFlags);
                            if (SourceField != null && SourceField.CanRead)
                            {
                                Control sourceControl = SourceField.GetValue(source, null) as Control;
                                if (sourceControl != null)
                                    controlID = sourceControl.UniqueID;
                            }
                            else
                                throw new NotSupportedException("The property corresponding to ControlID may not be read");
                        }

                        break;
                    }
                }
            }
            else
                return null;

            return controlID;
        }

        #endregion
    }
}
